<template>
    <div class="hsa-table" :class="HsaClass">
        <!-- 表格 -->
        <div class="hsa-table__table">
            <el-radio-group v-model="singleRadio">
                <el-table ref="tableContainer" header-cell-class-name="hsa-table__header-row" :data="dataList" border
                    empty-text="暂无内容" v-bind="$attrs">
                    <el-table-column v-for="column in columnList" :key="column._index_" v-bind="column">
                        <!-- 按钮组 -->
                        <template #default="scope: HsaTableScope<typeof dataList>" v-if="column.type == 'button'">
                            <template v-for="button in column.buttonGroup">
                                <el-button v-if="button.display ? button.display(scope.row) : true" size="small" text
                                    link :key="button._index_" v-bind="button"
                                    @click="button.click ? button.click(deepClone(scope.row), scope.$index, dataList) : null">
                                    {{ button.label }}
                                </el-button>
                            </template>
                        </template>

                        <!-- 单选 -->
                        <!-- <template #default="scope: HsaTableScope<typeof dataList>" v-else-if="column.type == 'single'">
                            <el-radio :value="(scope.row as Record<string, any>)[column.prop as string]" />
                        </template> -->

                        <!-- 自定义渲染 -->
                        <template #default="scope: HsaTableScope<object>" v-else-if="column.render">
                            <component :is="renderCell(column.render!, scope.row, scope.$index, columnList)" />
                        </template>
                         <!-- 自定义渲染表头 -->
                         <template #header="scope: HsaTableScope<object>" v-if="column.renderHeader">
                            <component :is="renderCell(column.renderHeader!, scope.row, scope.$index, columnList)" />
                        </template>
                    </el-table-column>
                    <template #empty>
                        <el-empty :image="Emptypng" />
                    </template>
                </el-table>
            </el-radio-group>
        </div>

        <!-- 分页 -->
        <div class="hsa-table__pagination" v-if="paginationEnable">
            <el-pagination v-bind="pagination" @size-change="sizeChange" @current-change="currentChange"
                @change="change" @prev-click="prevClick" @next-click="nextClick" />
        </div>
    </div>
</template>

<script setup lang="ts">
    import { ref, reactive, computed, h, type ComputedRef, type PropType } from 'vue'
    import { ElTable, ElTableColumn, ElRadioGroup, ElRadio, ElPagination, ElEmpty } from 'element-plus'
    import { type TableColumnInstance } from 'element-plus'
    import { deepClone } from '../../utils/copy'
    import Emptypng from '../../assets/img/empty.png'

    // 组件类型
    import type {
        HsaTableButton,
        HsaTableScope,
        HsaTableColumn,
        HsaTablePaginationProps,
        HsaTablePaginationEmits
    } from '../../types/table.d'

    // 修改接口定义
    interface PaginationDefault extends Omit<HsaTablePaginationProps, 'total'> {
        total: number | ComputedRef<number>
    }
    type UsableTableColumn = TableColumnInstance & HsaTableColumn & {
        _index_: string
        buttonGroup: (HsaTableButton & {
            _index_: string
        })[]
    }

    // 组件配置
    defineOptions({
        name: 'HsaTable'
    })

    // 组件属性
    const props = defineProps({
        // 数据
        data: {
            type: Array as PropType<Record<string, any>[]>,
            default: () => []
        },
        // 列定义
        columns: {
            type: Array as PropType<HsaTableColumn[]>,
            default: () => []
        },
        // 是否自适应高度
        autoHeight: {
            type: Boolean,
            default: false
        },
        // 单选
        single: {
            type: Boolean,
            default: false
        },
        // 单选属性
        singleProp: {
            type: String,
            default: ''
        },
        // 单选默认值
        singleDefault: {
            type: String,
            default: ''
        },
        // 是否显示序号
        showIndex: {
            type: Boolean,
            default: false
        },
        // 分页配置
        paginationConfig: {
            type: Object as PropType<HsaTablePaginationProps>,
            default: () => ({})
        },
        // 是否启用分页
        paginationEnable: {
            type: Boolean,
            default: true
        },
        // 是否使用外部分页
        paginationUseExternal: {
            type: Boolean,
            default: false
        },
    })

    // 组件事件
    const emit = defineEmits([
        'update:data',
        'update:columns',
        'radio-change',
        'pagination-size-change',
        'pagination-current-change',
        'pagination-change',
        'pagination-prev-click',
        'pagination-next-click'
    ])

    // 表格容器
    const tableContainer = ref<typeof ElTable>(null as any)

    // 单选
    const columnSingle = ref<HsaTableColumn>({
        label: '单选',
        type: 'default',
        width: 60,
        prop: props.singleProp,
        align: 'center',
        fixed: 'left',
        render: (row) => {
            if (!row[props.singleProp]) return ''
            return h(ElRadio, { value: row[props.singleProp], onChange: () => radioChange(row) })
        }
    })

    // 序号列
    const columnShowIndex = ref<HsaTableColumn>({
        label: '序号',
        type: 'index',
        width: 60,
        align: 'center',
        fixed: 'left',
        render: (_row, index) => {
            return index + 1
        }
    })

    // 单选项
    const singleRadio = ref<string | undefined>(props.singleDefault)

    // 处理自定义渲染函数
    const renderCell = (render: Function, row: any, index: number, columns: any[]) => {
        const result = render(row, index, columns)

        // 处理自定义渲染组件（支持双向绑定）
        // if (typeof result === 'object' && result !== null && 'component' in result && 'props' in result) {
        //     // 支持自定义组件和双向绑定
        //     // result格式: { component: 'el-input', props: { modelValue: row.fieldName, 'onUpdate:modelValue': (val) => row.fieldName = val } }
        //     return h(result.component, result.props, result.children || {})
        // }

        // 如果返回的是字符串，直接渲染文本
        if (typeof result === 'string') {
            // 检查是否是HTML字符串
            if (result.trim().startsWith('<') && result.includes('>')) {
                // 使用innerHTML渲染HTML内容
                return h('div', { innerHTML: result })
            }
            // 普通字符串，直接渲染文本
            return h('div', result)
        }

        // 如果返回的是数字，直接渲染文本
        if (typeof result === 'number') return h('div', result)

        // 如果返回的是VNode或者组件，则直接返回
        return result
    }

    // 列定义
    const columnList = computed({
        get: (): UsableTableColumn[] => {
            // 列表复杂处理
            const columns = props.columns.map(item => {
                // 按钮组处理
                const buttonGroup = () => {
                    if (item.type === 'button' && Array.isArray(item.buttonGroup)) {
                        return item.buttonGroup.map((button: HsaTableButton) => {
                            return {
                                ...button,
                                _index_: `${item.label}${new Date().getTime()}${Math.floor(Math.random() * 10000000)}`
                            }
                        })
                    }
                }

                // 返回处理后的列定义
                return {
                    ...item,
                    buttonGroup: buttonGroup(),
                    _index_: `${item.prop}${new Date().getTime()}${Math.floor(Math.random() * 10000000)}`
                } as any
            })

            // 是否显示单选
            if (props.single && props.singleProp) {
                return [columnSingle.value].concat(columns) as UsableTableColumn[]
            }

            // 是否显示序号
            if (props.showIndex) {
                return [columnShowIndex.value].concat(columns) as UsableTableColumn[]
            }
            // 返回处理后的列定义
            return columns
        },
        set: (value: HsaTableColumn[]) => {
            emit('update:columns', value)
        }
    })

    // 数据数量
    const dataTotal = computed(() => props.data.length)

    // 分页默认配置
    const paginationDefault = reactive<PaginationDefault>({
        size: "small",
        background: true,
        layout: "total, prev, pager, next, sizes, jumper",
        currentPage: 1,
        pageSize: 10,
        ...Object.assign({}, props.paginationConfig),
        total: dataTotal
    })

    // 数据
    const dataList = computed({
        get: (): Record<string, any>[] => {
            if (!props.paginationUseExternal) {
                const pageSize = paginationDefault.pageSize || 10
                const currentPage = paginationDefault.currentPage || 1
                const start = (currentPage - 1) * pageSize
                const end = currentPage * pageSize
                return props.data.slice(start, end)
            }
            return props.data
        },
        set: (value: Record<string, any>[]) => {
            emit('update:data', value)
        }
    })

    // 分页配置
    const pagination = computed({
        get() {
            if (props.paginationUseExternal) {
                return Object.assign({}, paginationDefault, props.paginationConfig)
            }
            return paginationDefault
        },
        set(value: any) {
            console.log('pagination', value)
        }
    })

    // 单选监听
    const radioChange = (row: any) => {
        emit('radio-change', deepClone(row))
    }

    // 分页:page-size 改变时触发
    const sizeChange: HsaTablePaginationEmits['onSizeChange'] = (pageSize: number, ...args) => {
        paginationDefault.pageSize = pageSize
        emit('pagination-size-change', pageSize, ...args)
    }

    // 分页:current-page 改变时触发
    const currentChange: HsaTablePaginationEmits['onCurrentPage'] = (currentPage: number, ...args) => {
        paginationDefault.currentPage = currentPage
        emit('pagination-current-change', currentPage, ...args)
    }

    // 分页:current-page 或 page-size 更改时触发
    const change: HsaTablePaginationEmits['onChange'] = (currentPage: number, pageSize: number, ...args) => {
        emit('pagination-change', currentPage, pageSize, ...args)
    }

    // 分页:用户点击上一页按钮改变当前页时触发
    const prevClick: HsaTablePaginationEmits['onPrevClick'] = (...args) => {
        emit('pagination-prev-click', ...args)
    }

    // 分页:用户点击下一页按钮改变当前页时触发
    const nextClick: HsaTablePaginationEmits['onNextClick'] = (...args) => {
        emit('pagination-next-click', ...args)
    }

    // 计算属性：根据 autoHeight 动态设置类名
    const HsaClass = computed(() => ({
        'hsa-table__auto': props.autoHeight
    }))

    // 暴露方法
    defineExpose({
        learSelection() {
            tableContainer.value.clearSelection()
        },
        getSelectionRows() {
            return tableContainer.value.getSelectionRows()
        },
        toggleRowSelection(row: any, selected: boolean) {
            tableContainer.value.toggleRowSelection(row, selected)
        },
        toggleAllSelection() {
            tableContainer.value.toggleAllSelection()
        },
        toggleRowExpansion(row: any, expanded: boolean) {
            tableContainer.value.toggleRowExpansion(row, expanded)
        },
        setCurrentRow(row: any) {
            tableContainer.value.setCurrentRow(row)
        },
        clearSort() {
            tableContainer.value.clearSort()
        },
        clearFilter(columnKey: string) {
            tableContainer.value.clearFilter(columnKey)
        },
        doLayout() {
            tableContainer.value.doLayout()
        },
        sort(prop: string, order: string) {
            tableContainer.value.sort(prop, order)
        },
        scrollTo(row: any, column: any) {
            tableContainer.value.scrollTo(row, column)
        },
        setScrollTop(top: number) {
            tableContainer.value.setScrollTop(top)
        },
        setScrollLeft(left: number) {
            tableContainer.value.setScrollLeft(left)
        },
        columns() {
            return tableContainer.value.columns
        },
        updateKeyChildren() {
            tableContainer.value.updateKeyChildren()
        },
        // 清空选中
        clearRadio() {
            singleRadio.value = undefined
        },
    })
</script>

<style lang="scss">
    .hsa-table {
        &__auto {
            height: 100%;
            width: 100%;
            display: flex;
            flex-direction: column;
        }

        .hsa-table__table {
            flex: 1;
            overflow-y: auto;

            // 优化滚动条样式
            &::-webkit-scrollbar {
                width: 6px;
            }

            &::-webkit-scrollbar-thumb {
                background-color: #dcdfe6;
                border-radius: 3px;
            }

            &::-webkit-scrollbar-track {
                background-color: #f5f7fa;
            }

            .el-radio-group {
                height: 100%;
                width: 100%;

                .el-radio {
                    .el-radio__label {
                        padding: 0;
                    }
                }
            }
        }

        .el-table {
            height: 100%;
            // // 修改表格边框颜色
            // --el-table-border-color: #ddd;

            // 只修改中间列的边框颜色
            .el-table__body {
                td.el-table__cell {
                    border-right-color: #aaa; // 右边框颜色
                }
            }

            .el-table__header {
                th.el-table__cell {
                    border-right-color: #aaa; // 表头右边框颜色
                }
            }

            .el-scrollbar__view,
            .el-table__empty-block {
                height: 100%;
            }
        }
    }

    // 表头
    .hsa-table__header-row {
        background-color: #F0F2F5 !important;
        color: #333;
    }

    // 分页
    .hsa-table__pagination {
        display: flex;
        text-align: right;
        padding-top: 20px;
        flex-direction: row-reverse;
    }
</style>